package pub.cleangao.codegen.enquiry.postgres;

import org.apache.commons.lang3.StringUtils;
import pub.cleangao.codegen.GenConfigHolder;
import pub.cleangao.codegen.enquiry.ColumnEnquiry;
import pub.cleangao.codegen.enquiry.ColumnInfo;
import pub.cleangao.codegen.enquiry.JavaColumnInfo;
import pub.cleangao.codegen.util.ClassField;

import java.util.Map;
import java.util.Set;

public class PostgresColumnEnquiry extends ColumnEnquiry {

    private static final PostgresTypeFormatter TYPE_FORMATTER = new PostgresTypeFormatter();
    private static final String SHOW_SQL =
            """
            SELECT   pg_attribute.attname AS colname,   atttypid::regtype AS type,   numeric_scale as SCALE,   C.is_nullable as NULLABLE,   col_description ( pg_attribute.attrelid, pg_attribute.attnum ) AS cmt,   pg_attribute.attnum = pg_constraint.conkey [ 1 ] AS is_pk,  CASE WHEN POSITION ( 'nextval' IN column_default ) > 0 THEN 1 ELSE 0 END AS is_identity  FROM   pg_constraint   RIGHT JOIN pg_class ON pg_constraint.conrelid = pg_class.oid   RIGHT JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid   RIGHT JOIN pg_type ON pg_type.oid = pg_attribute.atttypid   RIGHT JOIN information_schema.COLUMNS C ON C.TABLE_NAME = pg_class.relname    AND C.COLUMN_NAME = pg_attribute.attname   WHERE   pg_class.relname = '%s'  AND pg_attribute.attnum > 0
            """;
    public PostgresColumnEnquiry(GenConfigHolder config) {
        super(config);
    }


    @Override
    protected String getColumnInfoSql(String tableName) {
        return String.format(SHOW_SQL, tableName);
    }

    @Override
    protected ColumnInfo buildColumnInfo(Map<String, Object> rowMap) {
        Set<String> columnSet = rowMap.keySet();
        for (String columnInfo : columnSet) {
            rowMap.put(columnInfo.toUpperCase(), rowMap.get(columnInfo));
        }

        ColumnInfo columnInfo = new JavaColumnInfo();
        columnInfo.setColumnName(ClassField.convertString(rowMap.get("COLNAME")));
        boolean isIdentity = "1".equals(ClassField.convertString(rowMap.get("IS_IDENTITY")));
        columnInfo.setIsIdentity(isIdentity);
        boolean isPk = (Boolean) (rowMap.get("IS_PK") != null ? rowMap.get("IS_PK") : false);
        columnInfo.setIsPk(isPk);
        String type = ClassField.convertString(rowMap.get("TYPE"));
        // 如果是number
        if (StringUtils.containsIgnoreCase(type, "numeric")) {
            // 有精度则为decimal，否则是int
            Object scaleCol = rowMap.get("SCALE");
            if (scaleCol == null) {
                scaleCol = 0;
            }
            String scale = String.valueOf(scaleCol);
            type = "0".equals(scale) ? "integer" : "decimal";
        }
        columnInfo.setType(TYPE_FORMATTER.format(type));
        columnInfo.setComment(ClassField.convertString(rowMap.get("CMT")));
        String isNullable = ClassField.convertString(rowMap.get("NULLABLE"));
        columnInfo.setIsNullable(!"NO".equalsIgnoreCase(isNullable));
        return columnInfo;
    }
}
